package com.iocollege.tinyframe.common.service.impl;


//定义通用MYBATIS的抽象类

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.*;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.iocollege.tinyframe.common.core.domain.MQueryParam;
import com.iocollege.tinyframe.common.core.domain.QueryAndItems;
import com.iocollege.tinyframe.common.core.domain.QueryPagePara;
import com.iocollege.tinyframe.common.service.MyService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ResolvableType;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;


public class BaseMyService<M extends BaseMapper<T>, T> extends ServiceImpl<M, T> implements MyService<T> {


    @Autowired
    protected M baseMapper;

    @Override
    public M getBaseMapper() {
        return baseMapper;
    }

    protected Class<T> entityClass = currentModelClass();

    @Override
    public Class<T> getEntityClass() {
        return entityClass;
    }

    protected Class<T> mapperClass = currentMapperClass();

    @Override
    protected Class<T> currentMapperClass() {
        return (Class<T>) this.getResolvableType().as(BaseMyService.class).getGeneric(0).getType();
    }

    @Override
    protected Class<T> currentModelClass() {
        return (Class<T>) this.getResolvableType().as(BaseMyService.class).getGeneric(1).getType();
    }

    /**
     * @see ResolvableType
     * @since 3.4.3
     */
    protected ResolvableType getResolvableType() {
        return ResolvableType.forClass(ClassUtils.getUserClass(getClass()));
    }


    @Override
    public List<T> findByAttrName(String AttName, Object value) {
        QueryWrapper<T> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(AttName, value);
        return baseMapper.selectList(queryWrapper);

    }

    /**
     *
     * 按属性查询，只返回一个
     * @param AttName
     * @param value
     * @return
     */
    @Override
    public T findOndeByAttrName(String AttName, Object value) {

        List<T> mylist = findByAttrName(AttName,value);
        if(mylist.size()>0)
            return mylist.get(0);
        else
            return null;

    }


    @Override
    public Integer countByAttrName(String AttName, Object value) {
        QueryWrapper<T> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(AttName, value);
        return baseMapper.selectCount(queryWrapper);

    }


    @Override
    public IPage<T> findByAttrNameTopN(String AttName, Object value, Integer n, String orderCol, Boolean asc) {

        Page<T> page = new Page<>(1, n);
        QueryWrapper<T> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(AttName, value);
        if(asc){
            queryWrapper.orderByAsc(orderCol);
        }else{
            queryWrapper.orderByDesc(orderCol);
        }

        IPage<T> userIPage = baseMapper.selectPage(page, queryWrapper);

        return userIPage;

    }

    @Override
    public  IPage<T> getByPage(QueryPagePara mQuery) {
        QueryWrapper<T> example = new QueryWrapper<>();

        Integer currentPage = 1;

        Integer pageSize = 9999;//默认取相当大的值


        currentPage = mQuery.getOffset();
        pageSize = mQuery.getLimit();

        List<QueryAndItems> Pares = mQuery.getWherePara();  //获取4元组参数列表


        for (QueryAndItems items : Pares) {
            //现阶段只处理了and项，其它的还没有处理

            for (MQueryParam item : items.getQueryList()) {
                String op = item.getAction().replace(" ", "").toLowerCase();
                String P = item.getKey();


                    Object V1 = item.getValue1();
                    Object V2 = item.getValue2();

                    switch (op) {
                        case "=":
                            example.eq(P, V1);
                            break;
                        case "<":
                            example.lt(P, V1);
                            break;
                        case ">":
                            example.gt(P, V1);
                            break;
                        case "<=":
                            example.le(P, V1);
                            break;
                        case "=<":
                            example.le(P, V1);
                            break;
                        case ">=":
                            example.ge(P, V1);
                            break;
                        case "=>":
                            example.ge(P, V1);
                            break;
                        case "like":
                            example.like(P, "%" + V1 + "%");
                            break;
                        case "between":

                            String S1 = V1.toString();
                            String S2 = V2.toString();

                            if (!StringUtils.isAllBlank(S1) && (!StringUtils.isAllBlank(S2))){
                                example.between(P, S1,S2);
                            }


                            break;

                        default:
                            example.eq(P, V1);

                    }

            }
            //end of items


        }

        Page<T> page = new Page<>(currentPage, pageSize);
        IPage<T> userIPage = baseMapper.selectPage(page, example);

        return userIPage;
    }

    @Override
    public Map<String, Object> getByPage(QueryPagePara request, T entity) {
        return null;
    }

    @Override
    public Map<String, Object> selectByPageNumSize(QueryPagePara request, Supplier<?> s) {
        return null;
    }


    @Override
    public int removeByIds(Long[] ids){
        List<Long> longList = Arrays.asList(ids);

        return removeByIds(longList)?1:0;
    }

}